package val.to.UI;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import org.json.JSONException;
import org.json.JSONObject;
import val.to.BaseRequestListener;
import val.to.BitmapUtil;
import val.to.ErrorHelper;
import val.to.Globals;
import val.to.R;
import val.to.SessionEvents;
import val.to.SessionEvents.AuthListener;
import val.to.SessionEvents.LogoutListener;
import val.to.ValtoServices;
import val.to.common.SingleItemViewAdapter;
import val.to.entities.Event;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;

public class UserProfileActivity extends Activity {
	
	final int FACEBOOK_AUTHORIZE_ACTIVITY_REQUEST_CODE = 102;
	final int SHOW_SPINNER = 1010;
	
	
	Handler mHandler;
	String[] mPermissions = new String[] {"publish_stream", "user_photos","email"};
		
	// UI Controls
	LoginButton mLoginButton;
	TextView mLoginText;
	TextView mUserNameText;
	LinearLayout mUserDetailsLayout;
	ImageView mUserPic;
	TextView mCreateEventText;
	TextView mSelectEventText;
	ListView mOwnerEventsList;
	
	private ProgressDialog mSpinner;

    @Override
    public void onCreate(Bundle savedInstanceState) 
	{		
		super.onCreate(savedInstanceState);
        setContentView(R.layout.user_profile);
        
        mHandler = new Handler() {
        	public void handleMessage(android.os.Message msg) {
        		 switch (msg.what) {
        	      case SHOW_SPINNER:
        	        if (!isFinishing()) {
        	        	mSpinner.show();
        	        }
        	      break;
        	    }		
        	};
        };
        
        
        mSpinner = new ProgressDialog(this);
        mSpinner.requestWindowFeature(Window.FEATURE_NO_TITLE);
        mSpinner.setMessage(getString(R.string.logging_out));
        
        // add listeners for session events (login and logout events)
        SessionEvents.addAuthListener(new FacebookAuthListener());
        SessionEvents.addLogoutListener(new FacebookLogoutListener());        
        
        InitUIComponents();
        
        // if session is valid get user's info (currently just the display name)
        if (Globals.FacebookSession.isSessionValid())
        {
            requestUserData();
            loadEventsList();
        }
	}

	private void InitUIComponents()
	
	{
		// connect UI components to local variables
        mLoginButton = (LoginButton) findViewById(R.id.LoginButton);
        mUserNameText = (TextView) findViewById(R.id.userName);
        mLoginText = (TextView) findViewById(R.id.login_text);
        mCreateEventText = (TextView) findViewById(R.id.createEventButton);
        mSelectEventText = (TextView) findViewById(R.id.nearby_events_button);
        mUserPic = (ImageView) findViewById(R.id.userPicture);
        mUserDetailsLayout = (LinearLayout) findViewById(R.id.userDetails);
        mOwnerEventsList = (ListView)findViewById(R.id.ownerEventList);
       
        mUserNameText.setVisibility(View.INVISIBLE);
        
        // init login (logout) button
        mLoginButton.init(this, FACEBOOK_AUTHORIZE_ACTIVITY_REQUEST_CODE, Globals.FacebookSession, mPermissions);
        mLoginText.setVisibility(View.GONE);
        
        mCreateEventText.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				Intent intent = new Intent(v.getContext(), CreateEvent.class);
				startActivity(intent);
			}
		});
        
        mSelectEventText.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				Intent intent = new Intent(v.getContext(), EventsActivity.class);
				startActivity(intent);
			}
		});
       
	}
	
	@Override
    public void onResume() {
        super.onResume();
        if (Globals.FacebookSession.isSessionValid()) {
        	Globals.FacebookSession.extendAccessTokenIfNeeded(this, null);  
        	requestUserData(); 	
        }
        else{
        	mUserNameText.setText("You are logged out");
        }
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) 
    {
        super.onActivityResult(requestCode, resultCode, data);
        if(requestCode == FACEBOOK_AUTHORIZE_ACTIVITY_REQUEST_CODE)
        {
        	Globals.FacebookSession.authorizeCallback(requestCode, resultCode, data);
        }
    }
    
    // authentication listener
    public class FacebookAuthListener implements AuthListener 
    {
        @Override
        public void onAuthSucceed() {
            requestUserData();
        }

        @Override
        public void onAuthFail(String error) {
        	mLoginText.setVisibility(View.VISIBLE);
            mLoginText.setText("Login Failed: " + error);
        }
    }

    /*
     * The Callback for notifying the application when log out starts and
     * finishes.
     */
    public class FacebookLogoutListener implements LogoutListener {
        @Override
        public void onLogoutBegin() {
        	Message msg = new Message();
        	msg.what = SHOW_SPINNER;
        	mHandler.dispatchMessage(msg);
        }

        @Override
        public void onLogoutFinish() {  
        	mSpinner.dismiss(); //this method is tread-safe.
        	
    		/*
        	mUserNameText.setVisibility(View.INVISIBLE);
            mLoginText.setVisibility(View.VISIBLE);
            mUserPic.setVisibility(View.INVISIBLE);
            mMenuButtonsLayout.setVisibility(View.INVISIBLE);
            mSelectEventText.setVisibility(View.INVISIBLE);
            mOwnerTitleRow.setVisibility(View.INVISIBLE);
            mOwnerListRow.setVisibility(View.INVISIBLE);
            
        	mLoginText.setText("You have logged out! ");
        	*/
			Intent entrance = new Intent().setClass(UserProfileActivity.this, EntranceActivity.class);
			entrance.putExtra("afterLogout", "SoMuchFUNNNN");
			
			startActivity(entrance);
			finish();
       }
    }
    
    /*
     * Request user name, and picture to show on the main screen.
     */
    public void requestUserData() {
    	
    	if (Globals.ProfilePic == null){
        	mLoginText.setVisibility(View.VISIBLE);
	        mLoginText.setText("Retrieving profile information...");
	        Bundle params = new Bundle();
	        params.putString("fields", "name,picture");
	        Globals.AsyncRunner.request("me", params, new UserRequestListener());
    	}
    	else{
    		loadContent();
    	}
    }
    
    /*
     * Handles user's info (retrieved from facebook)
     */
    public class UserRequestListener extends BaseRequestListener {

        @Override
        public void onComplete(final String response, final Object state) {
            JSONObject jsonObject;
            try {
                jsonObject = new JSONObject(response);

                Globals.Name = jsonObject.getString("name");
                Globals.UserID = jsonObject.getString("id");
                String picUri = jsonObject.getString("picture");
                
                Globals.ProfilePic = BitmapUtil.getBitmap(picUri);
                
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                    	loadContent();
                    }
                });

            } catch (JSONException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
    
    private void loadEventsList()
    {         
        new AsyncTask<Void, Void, Void>() {
        	
        	private ArrayList<Event> mItems;
        	
			@Override
			protected Void doInBackground(Void... params) {
				mItems = ValtoServices.getOwnerEvents();
				
				//Sort desc order
				// Sort the new items
				if (mItems != null && mItems.size() > 0) {
					Collections.sort(mItems, new Comparator<Event>() {
						@Override
						public int compare(Event lhs, Event rhs) {
							return (int) ( rhs.getStartDate().getTime() - lhs.getStartDate().getTime()); // dsc													
						}
					});
				}

				return null;
			}
			
			@Override
			protected void onPreExecute() {
				super.onPreExecute();
				mOwnerEventsList.setAdapter(
						new SingleItemViewAdapter(
								UserProfileActivity.this, 
								R.string.Loading,
								true));
			}
			
			@Override
			protected void onPostExecute(Void result) {
				super.onPostExecute(result);
				
				if (mItems == null){
					mOwnerEventsList.setAdapter(
							new SingleItemViewAdapter(UserProfileActivity.this, 
									R.string.error_loading_events, 
									false,
									R.drawable.error_bw,
									ValtoServices.getLastServerError()));
					return;
				}
					
				if (mItems.size() > 0){
					mOwnerEventsList.setAdapter(new EventItemAdapter(mItems));
				}
				else{
					mOwnerEventsList.setAdapter(new SingleItemViewAdapter(UserProfileActivity.this, R.string.no_events, false));
				}
			}

        }.execute();
    }
    
    private void loadContent()
    {
    	mUserNameText.setText(Globals.Name);
    	mUserPic.setImageBitmap(Globals.ProfilePic);
    	
    	mLoginText.setVisibility(View.GONE);
    	mUserNameText.setVisibility(View.VISIBLE);
        mUserPic.setVisibility(View.VISIBLE);
    }
    
	
	private class EventItemAdapter extends BaseAdapter{
		
		private ArrayList<Event> m_items;
		private LayoutInflater m_inflater;
		
		public EventItemAdapter(ArrayList<Event> items){
			m_items = items;
			m_inflater = (LayoutInflater) UserProfileActivity.this.getLayoutInflater();
		}

		@Override
		public int getCount() {
			return m_items.size();
		}

		@Override
		public Object getItem(int arg0) {
			return m_items.get(arg0);
		}

		@Override
		public long getItemId(int position) {
			return m_items.get(position).getId();
		}

		@Override
        public View getView(int position, View convertView, ViewGroup parent) {
            if (convertView == null) {
                convertView = m_inflater.inflate(R.layout.event_owner_item, null);
            }
           
            TextView name  = (TextView) convertView.findViewById(R.id.name);
            TextView desc  = (TextView) convertView.findViewById(R.id.description);
            
            LinearLayout exportButton = (LinearLayout) convertView.findViewById(R.id.export_event_button);
            Event event = m_items.get(position); 

            name.setText(event.getName());
            desc.setText(event.getDescription().length() == 0 ? "" : event.getDescription() + " ");
            
            mOwnerEventsList.setOnItemClickListener(new OnItemClickListener() {
    			@Override
    			public void onItemClick(AdapterView<?> adapterView, View view,
    					int position, long l) {

    				Event event = (Event) adapterView.getAdapter().getItem(position);
    				Intent intent = new Intent(view.getContext(), CreateEvent.class);
    				
    				Bundle b = new Bundle();
    				b.putParcelable("val.to.entities.Event", event);
    				
    				intent.putExtras(b);
    				startActivity(intent);
    			}
    		});
            
            exportButton.setTag(event);
            exportButton.setOnClickListener(new View.OnClickListener() {
				
				@Override
				public void onClick(View v) {
					Event event = (Event)v.getTag();
					AlertDialog dialog = CreateExportQuestionDialog(event, v.getContext());
					dialog.show();
				}
			});
            
            return convertView;
        }
	}	
	
	AlertDialog CreateExportQuestionDialog(final Event event, final Context context)
	{	        	
    	AlertDialog.Builder builder = new AlertDialog.Builder(this);
    	builder.setTitle("Would you like to export the album to Facebook?");
    	
    	builder.setPositiveButton("OK", new DialogInterface.OnClickListener() 
    	{
			@Override
			public void onClick(DialogInterface dialog, int which) 
			{
				ExportEventTask task = new ExportEventTask(context);
				task.execute(event);
			}
		});
    	builder.setNegativeButton("Cancel", null);
    	final AlertDialog ad = builder.create();
    	return ad;
	}
	
	public class ExportEventTask extends AsyncTask<Event, Void, Void>{  
		
		ProgressDialog mDialog;
		Context mContext;
		boolean mResult;
		
		public ExportEventTask(Context context){
			mContext = context;
		}
		
		@Override
		protected Void doInBackground(Event... events) {
			Event updatedEvent = (Event)events[0];
			
			mResult = ValtoServices.exportEvent(updatedEvent);
			
			return null;
		}
		
		@Override
		protected void onPreExecute() {
			super.onPreExecute();
			mDialog = ProgressDialog.show(mContext, "", "Exporting Event Photos Album to Facebook...", true);	
		}
		
		@Override
		protected void onPostExecute(Void result) {
			super.onPostExecute(result);
			mDialog.dismiss();
			
			mHandler.post(new Runnable() {
				@Override
				public void run() {
					if (mResult){
						Toast.makeText(mContext, "Event Photos Album was exported successfully to Facebook", Toast.LENGTH_LONG).show();
					}
					else{
						ErrorHelper.showErrorAlert(mContext, "Event export was failed", ValtoServices.getLastServerError());
					}
					
					finish();
				}
			});
		}
	}
}
